#include "DbStorage/ProjectDbStorage.hpp"
#include "DbStorage/DbStorageFactory.hpp"
#include "Storage/PackageStorage.hpp"
#include "Storage/RequirementsStorage.hpp"
#include "Model/Project.hpp"
#include "CaseDB/SqlSvrConnection.hpp"
#include "CaseDB/Statement.hpp"
#include "CaseDB/RecordSet.hpp"
#include <cassert>

namespace DbStorage
{

ProjectDbStorage::ProjectDbStorage( Storage::StorageFactory& factory, CaseDB::Connection* pConnection )
	: DbStorageBase( pConnection)
	, Storage::ProjectStorage( factory)
{

}

// ---------------------------------------------------------------------------------------------------------------------

Model::Project* ProjectDbStorage::loadProject( const boost::any& projectID )
{
	using namespace CaseDB;

	Statement query( "select NAME, DESCRIPTION from PROJECTS where PK_PROJECT = ?" );
	query.addParameter( DbTypesEnum::Integer, boost::any_cast< int>( projectID));
	RecordSet::Metadata resultMeta;
	resultMeta.reserve(2);
	resultMeta.push_back( DbTypesEnum::String);
	resultMeta.push_back( DbTypesEnum::String);
	RecordSet results( resultMeta);
	dynamic_cast< DbStorageFactory&>( this->storageFactory()).dbConnection().execute( query, results);

	if( results.numberOfRecords() == 0)
	{
		assert( false);
		return NULL;
		// TODO: How to react if no data is found?
	}
	else
	{
		assert( 1 == results.numberOfRecords());
		RecordSet::ConstRecordIterator recI = results.begin();
		std::string name = boost::any_cast< std::string>( (*recI)[0]);
		std::string description = boost::any_cast< std::string>( (*recI)[1]);
		std::auto_ptr< Model::Project> pLoadedPrj( new Model::Project( 
			projectID, name, description));

		// Now, load the packages
		this->storageFactory().getPackageStorage().loadPackages( *pLoadedPrj);

		// Now, load the requirements
		this->storageFactory().getRequirementStorage().loadRequirements( *pLoadedPrj);
		
		return pLoadedPrj.release();
	}

}

} // namespace DbStorage
